<template>
  <el-upload class="upload-demo"
    :action="action"
    :limit="limit"
    :onSuccess="uploadSuccess"
    :on-error="uploadError"
    :on-preview="handlePreview"
    :before-remove="beforeFileRemove"
    :on-remove="onFileRemove"
    :headers="headers"
    :file-list="fileList"
    :on-exceed="handleExceed"
    :before-upload="beforeUpload"
    v-bind="$attrs">
    <el-button :size="size" type="primary" v-bind="$attrs">{{ uploadText }}</el-button>
    <div slot="tip" class="el-upload__tip">{{ uploadTip }}</div>
  </el-upload>
</template>

<script>
import Vue from 'vue'
import http from '@/utils/httpRequest'
import { downloadFile } from '@/utils/server'

export default {
  name: 'ZUpload',
  props: {
    size: {
      type: String,
      default: 'medium'
    },
    /** 上传文件接口 */
    action: {
      type: String,
      default: http.adornUrl('/sys/toolLocalStorage/save')
    },
    /** 文件列表。v-model 默认关联的属性 */
    value: {
      type: Array,
      default: () => []
    },
    /** 限制上传文件数量 */
    limit: {
      type: Number,
      default: 10
    },
    /** 限制上传文件类型以及大小 */
    limitFile: {
      type: Object,
      default: () => {
        return {
          type: ['png', 'jpeg', 'pdf', 'jpg', 'xlsx', 'xls', 'doc', 'docx', 'JPG', 'zip', 'rar', 'txt', 'ico'],
          size: 20
        }
      }
    },
    /** 点击文件事件 */
    handleClickFile: {
      type: Function,
      default: null
    },
    /** 上传按钮文本 */
    uploadText: {
      type: String,
      default: '点击上传'
    },
    /** 提示信息 */
    uploadTip: {
      type: String,
      default: ''
    },
    /** 删除文件时是否需要提示 */
    confirmDelShow: {
      type: Boolean,
      default: true
    }
  },
  inheritAttrs: false,
  headers: {},
  watch: {
    value (val) {
      this.fileList = val
    }
  },
  data () {
    return {
      headers: {},
      fileList: this.value
    }
  },
  created () {
    this.headers = {
      token: Vue.cookie.get('token')
    }
  },
  methods: {
    emit () {
      this.$emit('input', this.fileList)
      this.$emit('change', this.fileList)
    },
    /** 文件成功上传之后执行 */
    uploadSuccess (response, file, fileList) {
      const { code, data, msg } = response
      if (code === 0) {
        const obj = {
          name: data.name + '.' + data.suffix,
          filepath: data.path,
          fileId: data.storageId
        }
        this.fileList.push(obj)
        this.emit()
      } else {
        if (msg) {
          this.$message.error(msg)
        } else {
          this.$message.error('文件上传失败')
        }
      }
    },
    /** 上传失败 */
    uploadError (response, file, fileList) { },
    handlePreview (file) {
      // 如果点击文件不需要处理，则直接下载，否则调用传过来的方法
      if (this.handleClickFile === null) {
        if (file.filepath) {
          let baseUrl = ''
          if (location.port == '8877') {
            baseUrl = 'http://localhost:8080/'
          }
          window.open(baseUrl + file.filepath, '_blank')
        } else if (file.fileId) {
          downloadFile(file.fileId, file.name)
        }
      } else {
        this.handleClickFile(file)
      }
    },
    beforeFileRemove (file, fileList) {
      if (this.confirmDelShow && !this.fileDisable) {
        return this.$confirm(`确定移除 ${file.name}？`, '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        })
      } else {
        return true
      }
    },
    onFileRemove (file, fileList) {
      if (this.fileList.length) {
        const index = this.fileList.findIndex(
          item => item.fileId === file.fileId
        )
        if (index > -1) {
          this.fileList.splice(index, 1)
          this.emit()
        }
      }
    },
    // 上传数据处理
    beforeUpload: function (file) {
      const { type, size } = this.limitFile
      const fileName = file.name.split('.') // 文件
      const suffixName = fileName[fileName.length - 1]
      if (type && !type.includes(suffixName)) {
        this.$message({
          message: `请上传 ${type.toString()} 格式的文件!`,
          type: 'warning'
        })
        this.fileDisable = true
        return false
      }
      const isLt = file.size / 1024 / 1024 < size
      if (!isLt) {
        this.$message({
          message: `请上传大小不超过 ${size}MB 的文件!`,
          type: 'warning'
        })
        this.fileDisable = true
        return false
      }
      this.fileDisable = false
      return true
    },
    /** 限制文件上传的个数 */
    handleExceed (files, fileList) {
      this.$message.warning(
        `最多选择 ${this.limit} 个文件，本次选择了 ${
          files.length
        } 个文件，共选择了 ${files.length + fileList.length} 个文件`
      )
    }
  }
}
</script>
